<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- DOMtree和cssOM ==> renderTree ==> layout（第一次计算位置大小，布局） ==> paint(第一次绘制)-->
  <!-- 下载link引入的文件 不会阻塞DOMtree的生成过程，可能会阻塞renderTree的构建过程 -->
  <!-- DOMtree和renderTree不一定是一一对应的 -->
  <link rel="stylesheet" href="./css/style.css">  
  <!-- defer一定程度上可以提高浏览器性能 -->
  <!-- defer脚本一般放在head中 提前下载 -->
  <!-- defer属性只有在引入外部脚本时才有意义 -->
  <script src="./js/test.js" defer></script>
  <script src="./js/deferDemo.js" defer></script>
  <!-- async属性 让脚本完全独立 不会阻塞浏览器渲染页面 -->
  <!-- 但是async脚本不会保证执行顺序 -->
  <!-- 一旦async脚本下载完成，会立即执行脚本文件 -->  
  <script src="./js/test.js" async></script>
  <script src="./js/asyncDemo.js" async></script>
</head>
<body>
  <!-- 回流（重排）和重绘 -->
  <div class="box">box盒子</div>
  <p>我是内容</p>
  <!-- scipt标签会阻塞DOMtree的构建 -->
  <script src="./js/test.js"></script>
  <!-- 只有js代码解析完成才能继续渲染HTML页面 -->
  <!-- 原因：js可以操作和修改DOM元素 -->
  <button>修改box</button>

  <script>

    var boxEl = document.querySelector(".box")
    var btnEl = document.querySelector("button")
    btnEl.onclick = function() {
      // boxEl.remove()  页面的布局要发生变化  => 回流
      boxEl.style.height = "200px"
    }
    // 引起回流：1.修改DOM 2.改变元素的尺寸 3.getComputedStyle
    // 引起重绘：1.颜色等不会引起重新布局的样式修改
    function sum(num1, num2) {
      return num1 + num2
    }
    // 避免回流：1.样式的修改尽量放在一起 2.尽量避免频繁的操作DOM 3.对某些元素使用绝对定位，脱离标准流，不会影响其他元素

  </script>

  <!-- defer属性 -->
  <!-- 1.下载和执行需要很长的时间 -->
  <!-- 总结一: 加上defer之后, js文件的下载和执行, 不会阻塞后面的DOM Tree的构建  -->
  <!-- defer脚本由浏览器单独下载，下载完成之后等待DOMtree构建完成 => 执行脚本文件 => DOMContentLoaded-->
  <!-- defer脚本中可以操作DOM,DOMtree已经构建完成 -->
  <!-- 多个defer脚本可以保证执行顺序 -->
  <script>
    // 总结三: defer代码是在DOMContentLoaded事件发出之前执行
    window.addEventListener("DOMContentLoaded", () => {
      console.log("DOMContentLoaded")
    })
  </script>
  <h1>哈哈哈哈啊</h1>


</body>
</html>